/*
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 *
 * Copyright @2008 the original author or authors.
 */
package com.bluestone.core;

import java.util.HashMap;

import com.bluestone.util.Util;

/**
 * Press some key in the keyboard.
 * @author <a href="mailto:bluestone.daniel.q@gmail.com">daniel.q</a>
 * 
 */
public class InputKeyAction extends Action {

	public InputKeyAction(String type, String target, String value,
			String delay, String offset) {
		super(type, target, value, delay, offset);
	}

	/* Virtual key codes. */
	/**
     * Constant for the non-numpad <b>enter</b> key.
     */
	public static String ENTERKEY = "enter";

	/** Constant for the F5 function key. */
	public static String F5KEY = "f5";
	/**
     * Constant for the non-numpad <b>down</b> arrow key.
     */
	public static String DOWNKEY = "down";

	/**
     * Constant for the non-numpad <b>tab</b> key.
     */
	public static String TABKEY = "tab";
	/**
     * Constant for the non-numpad <b>space</b> key.
     */
	public static String SPACEKEY = "space";
	
	/**
     * Constant for the non-numpad <b>home</b> key.
     */
	public static String HOMEKEY = "home";
	/**
     * Constant for the non-numpad <b>left</b> arrow key.
     */
	public static String LEFTKEY ="left";
	/**
     * Constant for the non-numpad <b>right</b> arrow key.
     */
	public static String RIGHTKEY="right";
	/**
     * Constant for the non-numpad <b>end</b> arrow key.
     */
	public static String ENDKEY = "end";

	private int key = 0;
	
	private HashMap specailchars = new HashMap();

	/**
	 * Press some key in the keyboard.
	 */
	public boolean execute() {
		
		initSpecialChars();
		
		if (!super.execute()){
			return false;
		}
		boolean inputchar = false;
		if (ENTERKEY.equalsIgnoreCase(target)) {
			key = java.awt.event.KeyEvent.VK_ENTER;
		} else if (F5KEY.equalsIgnoreCase(target)) {
			key = java.awt.event.KeyEvent.VK_F5;
		} else if (DOWNKEY.equalsIgnoreCase(target)) {
			key = java.awt.event.KeyEvent.VK_DOWN;
		} else if (TABKEY.equalsIgnoreCase(target)) {
			key = java.awt.event.KeyEvent.VK_TAB;
		} else if (SPACEKEY.equalsIgnoreCase(target)) {
			key = java.awt.event.KeyEvent.VK_SPACE;
		} else if (HOMEKEY.equalsIgnoreCase(target)) {
			key = java.awt.event.KeyEvent.VK_HOME;
		} else if (LEFTKEY.equalsIgnoreCase(target)) {
			key = java.awt.event.KeyEvent.VK_LEFT;
		} else if (RIGHTKEY.equalsIgnoreCase(target)) {
			key = java.awt.event.KeyEvent.VK_RIGHT;
		} else if(ENDKEY.equalsIgnoreCase(target)){
			key = java.awt.event.KeyEvent.VK_END;
		} else{

			for (int i = 0; i < value.length(); i++) {
				char c = value.charAt(i);
				inputChar(c);
			}
			inputchar = true;
		}
		if(!inputchar){
			robot.keyPress(key);
			robot.delay(Util.getDelayTime(Util.DELAY200));
			robot.keyRelease(key);
		}

		if (delay != null && delay.length() > 0) {
			robot.delay(Util.getDelayTime(Integer.parseInt(delay)));
		} else {
			robot.delay(Util.getDelayTime(Util.INPUTKEYDELAY));
		}

		return true;
	}
	
	private void inputChar(char c){
		int [] rs = getKeyCode(c);
		if(rs.length == 1){
			robot.keyPress(rs[0]);
			robot.delay(Util.getDelayTime(Util.DELAY100));
			robot.keyRelease(rs[0]);
		
		}
		if(rs.length == 2){
			robot.keyPress(rs[0]);
			robot.delay(Util.getDelayTime(Util.DELAY100));
			robot.keyPress(rs[1]);
			robot.delay(Util.getDelayTime(Util.DELAY100));	
			robot.keyRelease(rs[1]);
			robot.delay(Util.getDelayTime(Util.DELAY100));				
			robot.keyRelease(rs[0]);			
		}
	    
	}
	private void initSpecialChars(){
		this.specailchars.put('!', '1');
		this.specailchars.put('@', '2');
		this.specailchars.put('#', '3');
		this.specailchars.put('$', '4');
		this.specailchars.put('%', '5');
		this.specailchars.put('^', '6');
		this.specailchars.put('&', '7');
		this.specailchars.put('*', '8');
		this.specailchars.put('(', '9');
		this.specailchars.put(')', '0');
		this.specailchars.put('_', '-');
		this.specailchars.put('+', '=');
		this.specailchars.put('{', '[');
		this.specailchars.put('}', ']');
		this.specailchars.put('|', '\\');
		this.specailchars.put(':', ';');
		this.specailchars.put('<', ',');
		this.specailchars.put('>', '.');
		this.specailchars.put('?', '/');			
	}
	private int [] getKeyCode(char c){
		int code = (int)c;
		int [] rs = null;
		
		//handle A-Z
		if(code >='A' && code<='Z'){
			rs = new int[2];
			rs[0] = java.awt.event.KeyEvent.VK_SHIFT;	
			rs[1] = code;
			return rs;
		}
		
		//handle a-z
		if(code>='a' && code<='z'){
			rs = new int[1];			
			rs[0] = code - 32;
			return rs;
		}
		
		//handle special char
		if(this.specailchars.containsKey(c)){
			rs = new int[2];
			rs[0] = java.awt.event.KeyEvent.VK_SHIFT;	
			rs[1] = ((Character)specailchars.get(c)).charValue();
			return rs;			
		}

		rs = new int[1];
		rs[0] = code;
		
		return rs;
	}

}
